/**
 * @file Document_plugin.h
 * @author Фетисов Михаил Вячеславович (fetisov.michael@yandex.ru)
 * @brief Объявления интерфейса плагина документа.
 * @version 0.1
 * @date 2023-02-15
 *
 * @copyright MIT: Michael Fetisov, Anton Bushev
 *
 */
#ifndef simodo_shell_document_Document_plugin_H
#define simodo_shell_document_Document_plugin_H

#include "simodo/shell/Plugin_interface.h"
#include "simodo/shell/access/Access_interface.h"
#include "simodo/shell/document/DocumentAdaptor_interface.h"
#include "simodo/shell/document/ViewAdaptor_interface.h"

#include <QVector>
#include <QSet>
#include <QIcon>

#include <memory>

namespace simodo::shell
{

/**
 * @brief Интерфейс плагина документа.
 *
 * Плагин документа является интерфейсом загружаемого плагина, связанного с представлением документов
 * в парадигме <a href="https://ru.wikipedia.org/wiki/Многодокументный_интерфейс">MDI</a>.
 *
 * @details
 * Плагин документа является фабрикой для адаптеров документа (см. DocumentAdaptor_interface) и
 * представления документа (см. ViewAdaptor_interface). Адаптер документа необходим для
 * осуществления связи оболочки с файлом документа. Представление документа отвечает за подготовку
 * и манипулирование виджетом документа, также являясь посредником между оболочкой и этим виджетом.
 *
 * Кроме функций фабрики плагин документа предоставляет для оболочки дополнительную информацию о
 * типах документов, которые он фабрикует.
 *
 */
class Document_plugin : public Plugin_interface
{
public:
    /**
     * @brief Перечень поддерживаемых расширений файлов.
     *
     * @todo Нужно реализовать более расширенный вариант с возвратом набора групп расширений с
     * их описанием. Т.е. нужно что-то типа QVector<FileExtensionGroup>, где FileExtensionGroup
     * содержит перечень расширений QVector<QString> и его описания QString.
     *
     * @return перечень поддерживаемых расширений файлов
     */
    virtual QVector<QString> file_extensions() const = 0;

    /**
     * @brief Наименование представления.
     *
     * Наименование представления может быть выведено для отображения во вкладке,
     * если для документа используется несколько представлений.
     *
     * @return Наименование представления
     */
    virtual QString view_name() const = 0;

    /**
     * @brief Короткое наименование представления, которое может быть использовано в меню,
     * подписях и т.д.
     *
     * @details
     * Короткое наименование желательно оформить так, чтобы можно было записать в продолжение
     * к слову "New ..."
     *
     * @return QString
     */
    virtual QString view_short_name() const = 0;

    /**
     * @brief Идентификаторов допустимых дополнительных представлений.
     *
     * Для работы с документом могут быть использованы другие представления с заданными расширениями.
     *
     * @return перечень идентификаторов допустимых дополнительных представлений
     */
    virtual QSet<QString> alternate_view_mnemonics(const QString & extention) const = 0;

    /**
     * @brief Создание нового адаптера документа.
     *
     * @param shell_access ссылка на интерфейс открытых функций оболочки
     * @return указатель на созданный адаптер документа
     */
    virtual std::shared_ptr<shell::DocumentAdaptor_interface> createDocumentAdaptor(Access_interface & shell_access) = 0;

    /**
     * @brief Создание нового адаптера представления документа.
     *
     * Если document_adaptor является нулевым указателем, значит нужно создать новый адаптер документа.
     *
     * @param shell_access ссылка на интерфейс открытых функций оболочки
     * @param document_adaptor указатель на адаптер документа, который нужно использовать для связи с файлом
     * @param path_to_file путь к файлу документа
     * @return указатель на созданный адаптер представления документа
     */
    virtual ViewAdaptor_interface * createViewAdaptor(Access_interface & shell_access,
                                        std::shared_ptr<shell::DocumentAdaptor_interface> document_adaptor,
                                        const QString & path_to_file) = 0;

    /**
     * @brief Имя темы иконки, связанной с поддерживаемыми типами документов.
     *
     * @return наименование темы
     */
    virtual QString icon_theme() const = 0;

    /**
     * @brief Иконка, обозначающая документ на вкладках
     *
     * @return объект иконки
     */
    virtual QIcon icon() const = 0;
};

}

#define DocumentPlugin_iid "BMSTU.SIMODO.shell.plugin.Document"

Q_DECLARE_INTERFACE(simodo::shell::Document_plugin, DocumentPlugin_iid)

#endif // simodo_shell_document_Document_plugin_H